import axios from "axios"
import { refreshToken } from "./users.js"
import { deepClone } from "../util/index.js"
import { Userstore } from "../store/User.js"
/* import { useRouter } from "vue-router" */
import router from "@/router"

const api = axios.create({
    baseURL: import.meta.env.VITE_BASE_API,
    timeout: 5000,
})
//缓存时效
const cacheExpirationTime = 1000 * 60 * 60; //1小时更新一次
const cacheMap = new Map();/* 路径和参数匹配 的 数据  key:String value:Object {time:xx,data:xx} */
const hasToCache = new Set(["/api/article/getarticle", "/api/article/getrecyclelist", "/api/lable/getalllables", "/api/user/getqiniutoken"]);/* 需要缓存的请求 匹配的是请求路径 '/api/article/getarticle'*/
const modifyCache = new Set(
    [
        { "/api/article/deleteArticle": "/api/article/getarticle" },
        { "/api/article/deleteArticle": "/api/article/getrecyclelist" },
        { "/api/article/edmitarticle": "/api/article/getarticle" },
        { "/api/article/edmitarticle": "/api/article/getrecyclelist" }
    ]
);/* 当发送一些请求时需要删除对应的缓存 比如说 修改文章的时候要删除 请求文章的缓存 */
//生成请求标识
function generateRequestKey(config, isRes = false) {
    let requestKey = config.url;
    // 响应返回的请求配置中的data是字符串，请求发送的请求配置中的data是对象
    if (isRes) {
        requestKey = requestKey + "-" + (config.data ?? "") + (JSON.stringify(config.params) ?? "");
    } else {
        requestKey = requestKey + "-" +
            (JSON.stringify(config.data) ?? "") +
            (JSON.stringify(config.params) ?? "");
    }
    return requestKey;
}
/* 响应拦截器 */
api.interceptors.response.use(async response => {
    let userstore = Userstore()
    /*  如果有token就存token */
    if (response.headers?.access_token) {
        localStorage.setItem('access_token', response.headers.access_token.split(" ")[1])
    }
    if (response.headers?.refresh_token) {
        localStorage.setItem('refresh_token', response.headers.refresh_token.split(' ')[1])
    }
    /* 单独对access_token失效的错误处理 */
    if (response.data?.status !== 200 && !response.config.url.includes('/refreshtoken')) {
        switch (response.data?.status) {
            case 401:
                if (localStorage.getItem('refresh_token')) {
                    let res = await refreshToken({
                        authorization: "Bearer" + " " + localStorage.getItem('refresh_token')
                    })
                    if (res.data.status === 200) {
                        /* 刷新token成功 1.更新用户信息 2.执行上次请求失败的接口 3.执行在刷新token时候发送的请求 */
                        userstore.storageUserInfo(res.data.data)
                        response.config.headers.Authorization = `Bearer` + " " + localStorage.getItem('access_token');
                        const resp = await api.request(response.config)
                        return resp
                    } else {
                        let errormsg = res.data.message.split(" ")[1]
                        if (errormsg === 'TokenExpiredError') {
                            /* reflsion_token也过期了 跳转登录页面清除用户信息 并提示用户 */
                            ElNotification({
                                title: 'Warning',
                                message: '请登录',
                                type: 'warning',
                            })
                            localStorage.removeItem("user");
                            router.push("/login")
                            userstore.isLogin = false
                        } else if (errormsg === 'JsonWebTokenError') {
                            /* 无效token 就直接导航到登录页 有人伪造token*/
                            ElNotification({
                                title: 'Warning',
                                message: '不要伪造token哦',
                                type: 'warning',
                            })
                            /* 清除用户信息 和 token */
                            localStorage.removeItem('access_token')
                            localStorage.removeItem('refresh_token')
                            localStorage.removeItem('user')
                            userstore.isLogin = false
                            router.push('/login')
                        }
                    }
                } else {
                    ElNotification({
                        title: 'Warning',
                        message: '请登录',
                        type: 'warning',
                    })
                    localStorage.clear()
                    router.push("/login")
                    userstore.isLogin = false
                }
                break;
            case 402:
                ElNotification({
                    title: 'Warning',
                    message: '没有权限,非超级管理员',
                    type: 'warning',
                })
                break;
            default:
                break;
        }
    }

    
    if (response.data?.status == 200) {
        const key = generateRequestKey(response.config, true);
        /* 如果是缓存黑名单，就删除 */
        modifyCache.forEach(item => {
            if (item[response.config.url]) {
                let clear = item[response.config.url]
                for (let item of cacheMap.keys()) {
                    let re = new RegExp(`${clear}`, 'g');
                    if (re.test(item)) {
                        cacheMap.delete(item)
                        cacheMap.get(item)
                    }
                }
            }
        })

        /* 如果这个路径是需要缓存就存进去 */
        if (!cacheMap.has(key)) {
            cacheMap.set(key, { cacheDate: new Date(), res: deepClone(response) });
        } else {
            /* 如果有这个缓存且缓存已经过期就更新缓存 */
            const requestCache = cacheMap.get(key);
            if (new Date() - requestCache.cacheDate > cacheExpirationTime) {
                cacheMap.set(key, {
                    cacheDate: new Date(),
                    res: deepClone(response),
                });
            }
        }

    }
    return response;
},
    error => {
        if (error.cached) {
            //返回缓存
            return Promise.resolve(deepClone(cacheMap.get(error.key).res));
        } else {
            // 对响应错误做点什么
            return Promise.reject(error);
        }
    }
)
// 设置默认的请求头
api.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 请求拦截器
api.interceptors.request.use(config => {
    if (hasToCache.has(config.url)) {
        /* 此路径需要缓存 查看cachemap里面是否包含有缓存 且时间没有过期 */
        let key = generateRequestKey(config)
        let cache = cacheMap.get(key)
        if (cache && Date.now() - cache.cacheDate < cacheExpirationTime) {
            return Promise.reject({
                cached: true,
                key,
            })
        }
    }
    // 可以在这里面进行一些校验之类的 比如数据大小，请求重复
    if (localStorage.getItem('access_token')) {
        if (!config.headers["authorization"]) {
            config.headers['authorization'] = "Bearer" + " " + localStorage.getItem('access_token')
        } else {
        }
    }
    return config
}, error => {
    console.log(error)
    Promise.reject(error)
})




export default api